package com.example.workapp;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.webkit.MimeTypeMap;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;


public class BluetoothClientActivity extends AppCompatActivity {

    private static final String TAG = "BluetoothReceiverActivity";
    private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");//
    private BluetoothAdapter bluetoothAdapter;
    private BluetoothServerSocket serverSocket;
    private BluetoothSocket socket;
    private BroadcastReceiver pairingReceiver;
    private BroadcastReceiver connectionReceiver;

    private static final int REQUEST_PERMISSION = 1;
    private static final int REQUEST_ENABLE_BT = 2;
    private static final int REQUEST_DISCOVERABLE = 3;
    private AlertDialog fileReceivedDialog; // 保存 Dialog 的引用


    private void startFileReceivingService() {
        try {
            // 创建监听Socket
            BluetoothServerSocket serverSocket = bluetoothAdapter.listenUsingRfcommWithServiceRecord(
                    "BluetoothFileTransfer", MY_UUID);
            // 在单独线程中接收连接和文件
            new Thread(() -> {
                try {
                    socket = serverSocket.accept();
                    receiveFile(socket);
                    socket.close();
                    serverSocket.close();
                } catch (IOException e) {
                    Log.e(TAG, "Error in file receiving service", e);
                    runOnUiThread(() ->
                            Toast.makeText(BluetoothClientActivity.this,
                                    "文件接收失败: " + e.getMessage(),
                                    Toast.LENGTH_SHORT).show()
                    );
                }
            }).start();
        } catch (IOException e) {
            Log.e(TAG, "Failed to create server socket", e);
            Toast.makeText(this, "无法创建服务套接字", Toast.LENGTH_SHORT).show();
        }
    }
    private void showPairingConfirmationDialog(BluetoothDevice device) {
        new AlertDialog.Builder(this)
                .setTitle("蓝牙配对请求")
                .setMessage("是否允许设备 " + device.getName() + " 配对？")
                .setPositiveButton("允许", (dialog, which) -> {
                    try {
                        device.getClass().getMethod("setPairingConfirmation", boolean.class).invoke(device, true);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                })
                .setNegativeButton("拒绝", (dialog, which) -> {
                    try {
                        device.getClass().getMethod("cancelPairingUserInput", boolean.class).invoke(device, true);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                })
                .show();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bluetooth_client);

        Log.d(TAG, "onCreate: Activity created");

        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();//蓝牙地址对应的
        if (bluetoothAdapter == null) {
            Log.e(TAG, "onCreate: Bluetooth not supported");
            Toast.makeText(this, "此设备不支持蓝牙", Toast.LENGTH_SHORT).show();
            finish();
        }
        requestBluetoothPermissions();

    }

    private void requestBluetoothPermissions() {
        List<String> permissionsToRequest = new ArrayList<>();

        // Check Bluetooth permissions based on Android version
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            // Android 12 and above require specific Bluetooth permissions
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT)
                    != PackageManager.PERMISSION_GRANTED) {
                permissionsToRequest.add(Manifest.permission.BLUETOOTH_CONNECT);
            }
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN)
                    != PackageManager.PERMISSION_GRANTED) {
                permissionsToRequest.add(Manifest.permission.BLUETOOTH_SCAN);
            }

        } else {
            // For older Android versions
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH)
                    != PackageManager.PERMISSION_GRANTED) {
                permissionsToRequest.add(Manifest.permission.BLUETOOTH);
            }
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_ADMIN)
                    != PackageManager.PERMISSION_GRANTED) {
                permissionsToRequest.add(Manifest.permission.BLUETOOTH_ADMIN);
            }
        }

        if (!permissionsToRequest.isEmpty()) {
            // Request permissions
            ActivityCompat.requestPermissions(
                    this,
                    permissionsToRequest.toArray(new String[0]),
                    REQUEST_PERMISSION
            );
        } else {
            // All permissions granted, proceed with Bluetooth setup
            setupBluetoothReceiver();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_PERMISSION) {
            boolean allPermissionsGranted = true;
            for (int result : grantResults) {
                if (result != PackageManager.PERMISSION_GRANTED) {
                    allPermissionsGranted = false;
                    break;
                }
            }

            if (allPermissionsGranted) {
                setupBluetoothReceiver();
            } else {
                showPermissionDeniedDialog();
            }
        }
    }

    private void setupBluetoothReceiver() {
        // Check if Bluetooth is enabled
        if (!bluetoothAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            return;
        }

        // Register Bluetooth receivers
        registerPairingReceiver();
        registerConnectionReceiver();

        // Start file receiving service
        startFileReceivingService();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_ENABLE_BT) {
            if (resultCode == RESULT_OK) {
                // Bluetooth is now enabled, proceed with setup
                setupBluetoothReceiver();
            } else {
                Toast.makeText(this, "Bluetooth must be enabled for file transfer", Toast.LENGTH_SHORT).show();
                finish();
            }
        }
    }

    private void registerPairingReceiver() {
        pairingReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if (BluetoothDevice.ACTION_PAIRING_REQUEST.equals(action)) {
                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    showPairingConfirmationDialog(device);
                }
            }
        };

        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST);
        registerReceiver(pairingReceiver, filter);
    }

    private void registerConnectionReceiver() {
        connectionReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
                    int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE);
                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                    switch (bondState) {
                        case BluetoothDevice.BOND_BONDED:
                            // 配对成功，准备接收文件
                            Log.d("BluetoothServer", "与设备 " + device.getName() + " 配对成功");
                            startFileReceivingService();
                            break;
                        case BluetoothDevice.BOND_BONDING:
                            Log.d("BluetoothServer", "正在与设备 " + device.getName() + " 配对");
                            break;
                        case BluetoothDevice.BOND_NONE:
                            Log.d("BluetoothServer", "与设备 " + device.getName() + " 配对失败");
                            break;
                    }
                }
            }
        };

        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        registerReceiver(connectionReceiver, filter);
    }

    private void showPermissionDeniedDialog() {
        new AlertDialog.Builder(this)
                .setTitle("权限被拒绝")
                .setMessage("您已永久拒绝了某些关键权限。请前往设置页面手动授予权限。")
                .setPositiveButton("去设置", (dialog, which) -> {
                    // 打开应用设置页面
                    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                    Uri uri = Uri.fromParts("package", getPackageName(), null);
                    intent.setData(uri);
                    startActivity(intent);
                })
                .setNegativeButton("退出应用", (dialog, which) -> {
                    // 退出应用
                    finish();
                })
                .setCancelable(false)
                .show();
    }


    private void receiveFile(BluetoothSocket socket) {
        InputStream inputStream = null;
        FileOutputStream fileOutputStream = null;
        OutputStream outputStream = null;
        try {
            inputStream = socket.getInputStream();
            outputStream = socket.getOutputStream();
            Log.d(TAG, "receiveFile: Input and output streams obtained");

            // 读取 MIME 类型长度
            byte[] mimeTypeLengthBuffer = new byte[4];
            int bytesRead = inputStream.read(mimeTypeLengthBuffer);
            if (bytesRead != 4) {
                throw new IOException("Failed to read MIME type length from client");
            }
            int mimeTypeLength = bytesToInt(mimeTypeLengthBuffer);
            Log.d(TAG, "MIME type length: " + mimeTypeLength);

            // 读取 MIME 类型内容
            byte[] mimeTypeBytes = new byte[mimeTypeLength];
            bytesRead = inputStream.read(mimeTypeBytes);
            if (bytesRead != mimeTypeLength) {
                throw new IOException("Failed to read MIME type from client");
            }
            String mimeType = new String(mimeTypeBytes, StandardCharsets.UTF_8);
            Log.d(TAG, "MIME type: " + mimeType);

            // 读取文件大小
            byte[] fileSizeBuffer = new byte[8];
            bytesRead = inputStream.read(fileSizeBuffer);
            if (bytesRead != 8) {
                throw new IOException("Failed to read file size from client");
            }
            long fileSize = bytesToLong(fileSizeBuffer);
            Log.d(TAG, "receiveFile: File size to receive: " + fileSize);

            // 选择文件保存路径
            String fileExtension = getFileExtensionFromMimeType(mimeType);
            String fileName = "received_file_" + System.currentTimeMillis() + "." + fileExtension;
            String outputPath = getAppExternalPath(fileName);
            File receivedFile = new File(outputPath);

            if (outputPath == null) {
                Log.e(TAG, "Failed to get external storage path");
                throw new IOException("Failed to get external storage path");
            }
            fileOutputStream = new FileOutputStream(outputPath);

            byte[] buffer = new byte[1024];
            long totalBytesRead = 0;

            // 从输入流读取并写入到文件
            while (totalBytesRead < fileSize) {
                bytesRead = inputStream.read(buffer);
                if (bytesRead == -1) {
                    break;
                }
                fileOutputStream.write(buffer, 0, bytesRead);
                totalBytesRead += bytesRead;
                Log.d(TAG, "receiveFile: Bytes read: " + totalBytesRead + "/" + fileSize);
            }

            if (totalBytesRead == fileSize) {
                Log.d(TAG, "receiveFile: File received successfully");

                // 发送确认信号给客户端
                outputStream.write(new byte[]{1});
                outputStream.flush();
                Log.d(TAG, "receiveFile: Confirmation sent to client");

                // 显示弹窗
                runOnUiThread(() -> {
                    if (!isFinishing() && !isDestroyed()) {
                        Log.d(TAG, "Attempting to show file received dialog");
                        showFileReceivedDialog(receivedFile);
                    } else {
                        Log.e(TAG, "Activity is finishing or destroyed, cannot show dialog");
                    }
                });

            } else {
                throw new IOException("File transfer incomplete. Expected: " + fileSize + ", Received: " + totalBytesRead);
            }
        } catch (IOException e) {
            Log.e(TAG, "receiveFile: Error receiving file: " + e.getMessage(), e);
        } finally {
            try {
                if (fileOutputStream != null) fileOutputStream.close();
                if (inputStream != null) inputStream.close();
                if (outputStream != null) outputStream.close();
            } catch (IOException e) {
                Log.e(TAG, "receiveFile: Error closing streams: " + e.getMessage(), e);
            }
        }
    }

    private void showFileReceivedDialog(File receivedFile) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("文件接收成功");
        builder.setMessage("文件已保存到: " + receivedFile.getAbsolutePath());

        // 打开文件所在位置
        builder.setPositiveButton("打开", (dialog, which) -> {
            openFileLocation(receivedFile);
            finish();  // 完成后关闭活动
        });

        // 取消操作
        builder.setNegativeButton("取消", (dialog, which) -> {
            dialog.dismiss();
            finish();  // 完成后关闭活动
        });

        // 显示弹窗
        fileReceivedDialog = builder.create();
        fileReceivedDialog.show();
    }

    // 打开文件所在位置
    private void openFileLocation(File file) {
        if (!file.exists()) {
            Toast.makeText(this, "文件不存在", Toast.LENGTH_SHORT).show();
            return;
        }

        Intent intent = new Intent(Intent.ACTION_VIEW);
        Uri fileUri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", file); // 使用 FileProvider 获取 Uri
        Log.d(TAG, "fileURI: " + fileUri);


        // 根据文件类型设置 MIME 类型
        String mimeType = getMimeType(file.getAbsolutePath());
        Log.d(TAG, "MimeTypr: " + mimeType);

        intent.setDataAndType(fileUri, mimeType);

        // 授予临时读取权限
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

        // 启动文件管理器
        if (intent.resolveActivity(getPackageManager()) != null) {
            startActivity(intent);
        } else {
            Toast.makeText(this, "未找到文件管理器", Toast.LENGTH_SHORT).show();
            Log.e(TAG, "未找到支持 MIME 类型 " + mimeType + " 的文件");
        }
    }

    // 获取文件的 MIME 类型
    private String getMimeType(String filePath) {
        String extension = filePath.substring(filePath.lastIndexOf(".") + 1);
        return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase());
    }

    // 将字节数组转换为long
    private long bytesToLong(byte[] bytes) {
        long value = 0;
        for (int i = 0; i < 8; i++) {
            value = (value << 8) | (bytes[i] & 0xFF);
        }
        return value;
    }

    // 获取应用特定的外部存储路径
    private String getAppExternalPath(String fileName) {
        File file = new File(getExternalFilesDir(null), fileName);
        return file.getAbsolutePath();
    }

    private static int bytesToInt(byte[] bytes) {
        return (bytes[0] & 0xFF) << 24 |
                (bytes[1] & 0xFF) << 16 |
                (bytes[2] & 0xFF) << 8  |
                (bytes[3] & 0xFF);
    }

    private String getFileExtensionFromMimeType(String mimeType) {
        switch (mimeType) {
            case "image/jpeg":
                return "jpg";
            case "image/png":
                return "png";
            case "application/pdf":
                return "pdf";
            case "text/plain":
                return "txt";
                case "text/xml":
            case "application/xml":
                return "xml"; //
            // 添加更多 MIME 类型和扩展名的映射
            default:
                return "bin"; // 默认扩展名
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 取消注册广播接收器
        if (pairingReceiver != null) {
            unregisterReceiver(pairingReceiver);
        }
        if (connectionReceiver != null) {
            unregisterReceiver(connectionReceiver);
        }
    }
}